package com.example.app;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;
import javafx.util.Callback;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class NotesTerminalApp extends Application {
    
    private ObservableList<Note> notes;
    private ListView<Note> notesList;
    private TextArea terminalArea;
    private TextField commandInput;
    private Label statusLabel;
    private Note currentNote;
    private List<String> commandHistory;
    private int historyIndex;
    
    // 笔记数据类
    public static class Note {
        private String title;
        private String content;
        private LocalDateTime lastModified;
        private String host;
        private int port;
        private String username;
        private String password;
        
        public Note(String title, String content) {
            this.title = title;
            this.content = content;
            this.lastModified = LocalDateTime.now();
        }
        
        public Note(String title, String host, int port, String username, String password) {
            this.title = title;
            this.host = host;
            this.port = port;
            this.username = username;
            this.password = password;
            this.content = "Redis连接: " + host + ":" + port;
            this.lastModified = LocalDateTime.now();
        }
        
        public String getTitle() { return title; }
        public void setTitle(String title) { this.title = title; }
        public String getContent() { return content; }
        public void setContent(String content) { 
            this.content = content;
            this.lastModified = LocalDateTime.now();
        }
        public LocalDateTime getLastModified() { return lastModified; }
        
        public String getHost() { return host; }
        public void setHost(String host) { this.host = host; }
        public int getPort() { return port; }
        public void setPort(int port) { this.port = port; }
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
        
        public String getPreview() {
            if (content == null || content.trim().isEmpty()) {
                return "无附加文本";
            }
            String preview = content.replaceAll("\\n", " ").trim();
            return preview.length() > 50 ? preview.substring(0, 50) + "..." : preview;
        }
        
        public String getFormattedDate() {
            return lastModified.format(DateTimeFormatter.ofPattern("yyyy/M/d"));
        }
    }

    @Override
    public void start(Stage primaryStage) {
        // 初始化数据
        initializeData();
        
        // 创建主布局
        BorderPane root = new BorderPane();
        root.setStyle("-fx-background-color: #f5f5f5;");
        
        // 创建左侧面板（备忘录风格）
        VBox leftPanel = createLeftPanel();
        
        // 创建右侧面板（终端风格）
        VBox rightPanel = createTerminalPanel();
        
        // 创建分割面板
        SplitPane splitPane = new SplitPane();
        splitPane.setOrientation(Orientation.HORIZONTAL);
        splitPane.getItems().addAll(leftPanel, rightPanel);
        splitPane.setDividerPositions(0.3);
        splitPane.setStyle("-fx-background-color: #f5f5f5;");
        
        root.setCenter(splitPane);
        
        // 创建场景
        Scene scene = new Scene(root, 1200, 800);
        
        // 设置舞台属性
        primaryStage.setTitle("备忘录 - 终端界面");
        primaryStage.setScene(scene);
        primaryStage.setResizable(true);
        primaryStage.show();
        
        // 默认选择第一个笔记
        if (!notes.isEmpty()) {
            notesList.getSelectionModel().select(0);
            selectNote(notes.get(0));
        }
    }
    
    private void initializeData() {
        notes = FXCollections.observableArrayList();
        commandHistory = new ArrayList<>();
        historyIndex = -1;
        
        // 添加示例数据
        notes.add(new Note("2025年07月", "2025年7月3日 11:56\n\n这是一个模仿macOS备忘录界面的JavaFX应用程序。\n\n功能特点：\n• 左侧笔记列表\n• 右侧终端界面\n• 实时保存\n• 日期显示"));
        notes.add(new Note("2025年06月", "夏季计划\n\n1. 学习JavaFX开发\n2. 完成桌面应用项目\n3. 优化用户界面设计"));
        notes.add(new Note("MDC支持规则", "2025/6/3 支持内容规则\n\n• 支持Markdown格式\n• 支持富文本编辑\n• 支持图片插入"));
        notes.add(new Note("系统安全相关", "安全配置检查清单：\n\n1. 网络安全设置\n2. 用户权限管理\n3. 数据备份策略"));
        notes.add(new Note("文件整理统计", "2025/6/29 文件整理文本\n\n已整理文件：\n• 文档类：156个\n• 图片类：89个\n• 代码类：234个"));
        notes.add(new Note("AI项目训练", "2025/5/7 之前的清单，是不是最新...\n\n训练进度：\n• 数据预处理：完成\n• 模型训练：进行中\n• 效果评估：待开始"));
        notes.add(new Note("2025年04月", "2025/5/5 2025年04月07日\n\n四月总结：\n• 完成了3个重要项目\n• 学习了新的技术栈\n• 参加了技术分享会"));
        notes.add(new Note("处理可见设备API", "2025/4/23 处理可见设备...\n\nAPI接口文档：\n• 设备发现接口\n• 设备控制接口\n• 状态监控接口"));
        notes.add(new Note("cursor使用说明", "2025/4/16 相关推荐条...\n\nCursor编辑器使用技巧：\n• 智能代码补全\n• AI辅助编程\n• 快捷键配置"));
    }
    
    private VBox createLeftPanel() {
        VBox leftPanel = new VBox();
        leftPanel.setStyle("-fx-background-color: #ffffff; -fx-border-color: #e0e0e0; -fx-border-width: 0 1 0 0;");
        leftPanel.setPrefWidth(300);
        
        // 创建顶部工具栏
        HBox toolbar = new HBox();
        toolbar.setPadding(new Insets(10));
        toolbar.setStyle("-fx-background-color: #f8f8f8; -fx-border-color: #e0e0e0; -fx-border-width: 0 0 1 0;");
        
        Button newNoteButton = new Button("+");
        newNoteButton.setStyle("-fx-background-color: #007AFF; -fx-text-fill: white; -fx-font-size: 16px; -fx-font-weight: bold; -fx-background-radius: 15; -fx-min-width: 30; -fx-min-height: 30;");
        newNoteButton.setOnAction(e -> createNewNote());
        
        toolbar.getChildren().add(newNoteButton);
        
        // 创建笔记列表
        notesList = new ListView<>(notes);
        notesList.setStyle("-fx-background-color: #ffffff; -fx-border-color: transparent;");
        
        // 自定义列表单元格
        notesList.setCellFactory(new Callback<ListView<Note>, ListCell<Note>>() {
            @Override
            public ListCell<Note> call(ListView<Note> param) {
                return new ListCell<Note>() {
                    @Override
                    protected void updateItem(Note note, boolean empty) {
                        super.updateItem(note, empty);
                        if (empty || note == null) {
                            setText(null);
                            setGraphic(null);
                        } else {
                            VBox cellContent = new VBox(2);
                            cellContent.setPadding(new Insets(8, 12, 8, 12));
                            
                            Label titleLabel = new Label(note.getTitle());
                            titleLabel.setFont(Font.font("System", FontWeight.BOLD, 14));
                            titleLabel.setTextFill(Color.BLACK);
                            
                            Label dateLabel = new Label(note.getFormattedDate());
                            dateLabel.setFont(Font.font("System", 11));
                            dateLabel.setTextFill(Color.GRAY);
                            
                            Label previewLabel = new Label(note.getPreview());
                            previewLabel.setFont(Font.font("System", 12));
                            previewLabel.setTextFill(Color.DARKGRAY);
                            previewLabel.setWrapText(false);
                            
                            cellContent.getChildren().addAll(titleLabel, dateLabel, previewLabel);
                            setGraphic(cellContent);
                            setText(null);
                        }
                        
                        // 设置选中样式
                        if (isSelected()) {
                            setStyle("-fx-background-color: #007AFF; -fx-text-fill: white;");
                        } else {
                            setStyle("-fx-background-color: transparent;");
                        }
                    }
                };
            }
        });
        
        // 添加选择监听器
        notesList.getSelectionModel().selectedItemProperty().addListener((obs, oldNote, newNote) -> {
            if (newNote != null) {
                selectNote(newNote);
            }
        });
        
        leftPanel.getChildren().addAll(toolbar, notesList);
        VBox.setVgrow(notesList, Priority.ALWAYS);
        
        return leftPanel;
    }
    
    private VBox createTerminalPanel() {
        VBox terminalPanel = new VBox();
        terminalPanel.setStyle("-fx-background-color: #fafafa;");
        
        // 创建顶部状态栏
        HBox statusBar = new HBox(10);
        statusBar.setPadding(new Insets(10, 15, 10, 15));
        statusBar.setAlignment(Pos.CENTER_LEFT);
        statusBar.setStyle("-fx-background-color: #f0f0f0; -fx-border-color: #d0d0d0; -fx-border-width: 0 0 1 0;");
        
        statusLabel = new Label("终端就绪");
        statusLabel.setFont(Font.font("System", FontWeight.BOLD, 14));
        statusLabel.setTextFill(Color.web("#007AFF"));
        
        Button clearButton = new Button("清空");
        clearButton.setStyle("-fx-background-color: #e0e0e0; -fx-text-fill: #333333; -fx-font-size: 12px; -fx-background-radius: 6; -fx-padding: 6 12; -fx-border-color: #c0c0c0; -fx-border-radius: 6;");
        clearButton.setOnAction(e -> clearTerminal());
        
        Region spacer = new Region();
        HBox.setHgrow(spacer, Priority.ALWAYS);
        
        statusBar.getChildren().addAll(statusLabel, spacer, clearButton);
        
        // 创建终端显示区域
        terminalArea = new TextArea();
        terminalArea.setEditable(false);
        terminalArea.setStyle("-fx-background-color: #ffffff; -fx-text-fill: #333333; -fx-font-family: 'SF Mono', 'Monaco', 'Consolas', 'Courier New', monospace; -fx-font-size: 13px; -fx-border-color: #e0e0e0; -fx-border-width: 1; -fx-border-radius: 8; -fx-background-radius: 8; -fx-focus-color: transparent; -fx-faint-focus-color: transparent; -fx-padding: 15;");
        terminalArea.setText("macOS 终端模拟器\n" +
                           "版本 1.0.0\n" +
                           "输入 'help' 查看可用命令\n\n");
        
        // 创建命令输入区域
        HBox inputBox = new HBox(8);
        inputBox.setPadding(new Insets(15, 15, 15, 15));
        inputBox.setAlignment(Pos.CENTER_LEFT);
        inputBox.setStyle("-fx-background-color: #f8f8f8; -fx-border-color: #e0e0e0; -fx-border-width: 1 0 0 0;");
        
        Label promptLabel = new Label("$");
        promptLabel.setFont(Font.font("SF Mono", FontWeight.BOLD, 13));
        promptLabel.setTextFill(Color.web("#007AFF"));
        
        commandInput = new TextField();
        commandInput.setStyle("-fx-background-color: #ffffff; -fx-text-fill: #333333; -fx-font-family: 'SF Mono', 'Monaco', 'Consolas', 'Courier New', monospace; -fx-font-size: 13px; -fx-border-color: #d0d0d0; -fx-border-radius: 6; -fx-background-radius: 6; -fx-focus-color: #007AFF; -fx-faint-focus-color: transparent; -fx-padding: 8 12;");
        commandInput.setPromptText("输入命令...");
        
        // 添加命令输入处理
        commandInput.setOnKeyPressed(event -> {
            if (event.getCode() == KeyCode.ENTER) {
                executeCommand();
            } else if (event.getCode() == KeyCode.UP) {
                showPreviousCommand();
            } else if (event.getCode() == KeyCode.DOWN) {
                showNextCommand();
            }
        });
        
        HBox.setHgrow(commandInput, Priority.ALWAYS);
        inputBox.getChildren().addAll(promptLabel, commandInput);
        
        terminalPanel.getChildren().addAll(statusBar, terminalArea, inputBox);
        VBox.setVgrow(terminalArea, Priority.ALWAYS);
        
        return terminalPanel;
    }
    
    private void selectNote(Note note) {
        currentNote = note;
        statusLabel.setText("当前连接: " + note.getTitle());
        
        // 清空终端并显示Redis连接信息
        clearTerminal();
        
        if (note.getHost() != null) {
            // 显示Redis连接信息
            appendToTerminal("\n=== Redis连接信息 ===\n");
            appendToTerminal("连接名称: " + note.getTitle() + "\n");
            appendToTerminal("主机地址: " + note.getHost() + "\n");
            appendToTerminal("端口: " + note.getPort() + "\n");
            if (note.getUsername() != null && !note.getUsername().isEmpty()) {
                appendToTerminal("用户名: " + note.getUsername() + "\n");
            }
            appendToTerminal("创建时间: " + note.getLastModified().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + "\n");
            appendToTerminal("状态: 准备连接\n");
            appendToTerminal("===================\n\n");
            appendToTerminal("提示: 输入Redis命令开始操作，例如: INFO, PING, KEYS *\n\n");
        } else {
            // 兼容旧的笔记格式
            appendToTerminal("\n=== 笔记内容 ===\n");
            appendToTerminal("标题: " + note.getTitle() + "\n");
            appendToTerminal("修改时间: " + note.getLastModified().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + "\n");
            appendToTerminal("内容:\n" + note.getContent() + "\n");
            appendToTerminal("================\n\n");
        }
    }
    
    private void createNewNote() {
        showRedisConnectionDialog();
    }
    
    private void showRedisConnectionDialog() {
        Dialog<Note> dialog = new Dialog<>();
        dialog.setTitle("新建Redis连接");
        dialog.setHeaderText("请输入Redis连接信息");
        
        // 设置按钮类型
        ButtonType connectButtonType = new ButtonType("连接", ButtonBar.ButtonData.OK_DONE);
        dialog.getDialogPane().getButtonTypes().addAll(connectButtonType, ButtonType.CANCEL);
        
        // 创建输入字段
        GridPane grid = new GridPane();
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setPadding(new Insets(20, 150, 10, 10));
        
        TextField hostField = new TextField();
        hostField.setPromptText("IP地址");
        hostField.setText("127.0.0.1");
        
        TextField portField = new TextField();
        portField.setPromptText("端口");
        portField.setText("6379");
        
        TextField usernameField = new TextField();
        usernameField.setPromptText("用户名(可选)");
        
        PasswordField passwordField = new PasswordField();
        passwordField.setPromptText("密码(可选)");
        
        TextField nameField = new TextField();
        nameField.setPromptText("连接名称(可选)");
        
        grid.add(new Label("主机:"), 0, 0);
        grid.add(hostField, 1, 0);
        grid.add(new Label("端口:"), 0, 1);
        grid.add(portField, 1, 1);
        grid.add(new Label("用户名:"), 0, 2);
        grid.add(usernameField, 1, 2);
        grid.add(new Label("密码:"), 0, 3);
        grid.add(passwordField, 1, 3);
        grid.add(new Label("连接名称:"), 0, 4);
        grid.add(nameField, 1, 4);
        
        dialog.getDialogPane().setContent(grid);
        
        // 设置焦点
        Platform.runLater(() -> hostField.requestFocus());
        
        // 转换结果
        dialog.setResultConverter(dialogButton -> {
            if (dialogButton == connectButtonType) {
                try {
                    String host = hostField.getText().trim();
                    int port = Integer.parseInt(portField.getText().trim());
                    String username = usernameField.getText().trim();
                    String password = passwordField.getText();
                    String connectionName = nameField.getText().trim();
                    
                    if (host.isEmpty()) {
                        showAlert("错误", "主机地址不能为空");
                        return null;
                    }
                    
                    if (connectionName.isEmpty()) {
                        connectionName = host + "@" + port;
                    }
                    
                    return new Note(connectionName, host, port, username, password);
                } catch (NumberFormatException e) {
                    showAlert("错误", "端口必须是有效的数字");
                    return null;
                }
            }
            return null;
        });
        
        Optional<Note> result = dialog.showAndWait();
        result.ifPresent(note -> {
            notes.add(0, note);
            notesList.getSelectionModel().select(0);
            selectNote(note);
        });
    }
    
    private void showAlert(String title, String message) {
        Alert alert = new Alert(Alert.AlertType.ERROR);
        alert.setTitle(title);
        alert.setHeaderText(null);
        alert.setContentText(message);
        alert.showAndWait();
    }
    
    private void executeCommand() {
        String command = commandInput.getText().trim();
        if (command.isEmpty()) return;
        
        // 添加到历史记录
        commandHistory.add(command);
        historyIndex = commandHistory.size();
        
        // 显示命令
        appendToTerminal("$ " + command + "\n");
        
        // 执行命令
        String response = processCommand(command);
        appendToTerminal(response + "\n");
        
        commandInput.clear();
    }
    
    private String processCommand(String command) {
        String[] parts = command.split("\\s+");
        if (parts.length == 0) return "命令不能为空";
        
        String cmd = parts[0].toUpperCase();
        
        // 检查当前是否选中了Redis连接
        if (currentNote != null && currentNote.getHost() != null) {
            return processRedisCommand(command, cmd, parts);
        } else {
            return processSystemCommand(command, cmd.toLowerCase(), parts);
        }
    }
    
    private String processRedisCommand(String originalCommand, String cmd, String[] parts) {
        // 模拟Redis命令响应
        switch (cmd) {
            case "PING":
                return "PONG";
            
            case "INFO":
                return "# Server\n" +
                       "redis_version:7.0.0\n" +
                       "redis_git_sha1:00000000\n" +
                       "redis_git_dirty:0\n" +
                       "redis_build_id:0\n" +
                       "redis_mode:standalone\n" +
                       "os:Darwin 21.6.0 x86_64\n" +
                       "arch_bits:64\n" +
                       "multiplexing_api:kqueue\n" +
                       "atomicvar_api:atomic-builtin\n" +
                       "gcc_version:4.2.1\n" +
                       "process_id:12345\n" +
                       "run_id:" + System.currentTimeMillis() + "\n" +
                       "tcp_port:" + currentNote.getPort() + "\n" +
                       "uptime_in_seconds:3600\n" +
                       "uptime_in_days:0\n";
            
            case "KEYS":
                if (parts.length < 2) {
                    return "(error) ERR wrong number of arguments for 'keys' command";
                }
                return "1) \"user:1001\"\n" +
                       "2) \"session:abc123\"\n" +
                       "3) \"cache:data\"\n" +
                       "4) \"config:app\"";
            
            case "GET":
                if (parts.length < 2) {
                    return "(error) ERR wrong number of arguments for 'get' command";
                }
                return "\"示例值: " + parts[1] + "\"";
            
            case "SET":
                if (parts.length < 3) {
                    return "(error) ERR wrong number of arguments for 'set' command";
                }
                return "OK";
            
            case "DEL":
                if (parts.length < 2) {
                    return "(error) ERR wrong number of arguments for 'del' command";
                }
                return "(integer) 1";
            
            case "EXISTS":
                if (parts.length < 2) {
                    return "(error) ERR wrong number of arguments for 'exists' command";
                }
                return "(integer) 1";
            
            case "TTL":
                if (parts.length < 2) {
                    return "(error) ERR wrong number of arguments for 'ttl' command";
                }
                return "(integer) -1";
            
            case "DBSIZE":
                return "(integer) 4";
            
            case "FLUSHDB":
                return "OK";
            
            case "SELECT":
                if (parts.length < 2) {
                    return "(error) ERR wrong number of arguments for 'select' command";
                }
                return "OK";
            
            case "HELP":
                return "Redis命令帮助:\n" +
                       "  PING - 测试连接\n" +
                       "  INFO - 显示服务器信息\n" +
                       "  KEYS pattern - 查找匹配的键\n" +
                       "  GET key - 获取键值\n" +
                       "  SET key value - 设置键值\n" +
                       "  DEL key - 删除键\n" +
                       "  EXISTS key - 检查键是否存在\n" +
                       "  TTL key - 获取键的过期时间\n" +
                       "  DBSIZE - 获取数据库大小\n" +
                       "  FLUSHDB - 清空当前数据库\n" +
                       "  SELECT db - 选择数据库";
            
            default:
                return "(error) ERR unknown command '" + cmd + "'";
        }
    }
    
    private String processSystemCommand(String command, String cmd, String[] parts) {
        switch (cmd) {
            case "help":
                return "可用命令:\n" +
                       "  help - 显示帮助信息\n" +
                       "  ls - 列出所有连接\n" +
                       "  cat [index] - 显示指定连接信息\n" +
                       "  echo [text] - 输出文本\n" +
                       "  date - 显示当前时间\n" +
                       "  clear - 清空终端\n" +
                       "  pwd - 显示当前位置\n" +
                       "  whoami - 显示当前用户";
            
            case "ls":
                StringBuilder connectionsList = new StringBuilder("连接列表:\n");
                for (int i = 0; i < notes.size(); i++) {
                    Note note = notes.get(i);
                    if (note.getHost() != null) {
                        connectionsList.append(String.format("%d. %s (%s:%d)\n", i + 1, note.getTitle(), note.getHost(), note.getPort()));
                    } else {
                        connectionsList.append(String.format("%d. %s (笔记)\n", i + 1, note.getTitle()));
                    }
                }
                return connectionsList.toString();
            
            case "cat":
                if (parts.length < 2) {
                    return "用法: cat [连接索引]";
                }
                try {
                    int index = Integer.parseInt(parts[1]) - 1;
                    if (index >= 0 && index < notes.size()) {
                        Note note = notes.get(index);
                        if (note.getHost() != null) {
                            return "=== " + note.getTitle() + " ===\n" +
                                   "主机: " + note.getHost() + "\n" +
                                   "端口: " + note.getPort() + "\n" +
                                   "用户名: " + (note.getUsername() != null ? note.getUsername() : "无") + "\n" +
                                   "创建时间: " + note.getLastModified().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                        } else {
                            return "=== " + note.getTitle() + " ===\n" + note.getContent();
                        }
                    } else {
                        return "错误: 连接索引超出范围";
                    }
                } catch (NumberFormatException e) {
                    return "错误: 无效的连接索引";
                }
            
            case "echo":
                if (parts.length < 2) {
                    return "";
                }
                return command.substring(5); // 去掉 "echo "
            
            case "date":
                return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss"));
            
            case "clear":
                Platform.runLater(() -> clearTerminal());
                return "";
            
            case "pwd":
                return "/Users/" + System.getProperty("user.name") + "/Documents/RedisConnections";
            
            case "whoami":
                return System.getProperty("user.name");
            
            default:
                return "命令未找到: " + cmd + "\n输入 'help' 查看可用命令";
        }
    }
    
    private void showPreviousCommand() {
        if (historyIndex > 0) {
            historyIndex--;
            commandInput.setText(commandHistory.get(historyIndex));
            commandInput.positionCaret(commandInput.getText().length());
        }
    }
    
    private void showNextCommand() {
        if (historyIndex < commandHistory.size() - 1) {
            historyIndex++;
            commandInput.setText(commandHistory.get(historyIndex));
            commandInput.positionCaret(commandInput.getText().length());
        } else if (historyIndex == commandHistory.size() - 1) {
            historyIndex = commandHistory.size();
            commandInput.clear();
        }
    }
    
    private void clearTerminal() {
        terminalArea.clear();
        terminalArea.setText("macOS 终端模拟器\n" +
                           "版本 1.0.0\n" +
                           "输入 'help' 查看可用命令\n\n");
    }
    
    private void appendToTerminal(String text) {
        Platform.runLater(() -> {
            terminalArea.appendText(text);
            terminalArea.setScrollTop(Double.MAX_VALUE);
        });
    }

    public static void main(String[] args) {
        launch(args);
    }
}